package org.example.r;

import org.rosuda.REngine.REXP;
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;

/**
 * @author 季舟
 * @Date 2025-01-16 13:28
 */
public class RClientDemo {
    /**
     * 程序的入口点
     * 该方法连接到R服务器，评估R的版本信息，并打印出来
     *
     * @param args 命令行参数
     * @throws RserveException 如果与R服务器的连接出现问题
     * @throws REXPMismatchException 如果从R服务器接收到的数据类型与预期不匹配
     */
    public static void main(String[] args) throws RserveException, REXPMismatchException {
        printRVersion();
    }

    /**
     * 打印R语言的版本信息
     *
     * 此方法通过连接R服务器来获取和打印R语言的版本信息它使用Rserve库与R服务器进行通信
     * 在调用此方法之前，需要确保R服务器已经启动，并且Rserve已经正确配置并连接到R服务器
     *
     * @throws RserveException 如果与R服务器的通信遇到问题
     * @throws REXPMismatchException 如果从R服务器接收到的数据类型与预期不匹配
     */
    public static void printRVersion() throws RserveException, REXPMismatchException {
        // 创建一个到R服务器的连接
        RConnection c = new RConnection();

        // 评估R的版本信息
        REXP x = c.eval("R.version.string");

        // 打印R的版本信息
        System.out.println(x.asString());

        // 关闭连接，释放资源
        c.close();
    }




    /**
     * 运行R脚本示例函数
     * 该函数连接到本地运行的Rserve，执行R代码以计算1到10的每个数字的平方，并打印结果
     *
     * @throws RserveException 如果与Rserve通信时发生错误
     * @throws REXPMismatchException 如果从R获取的数据类型与预期不符
     */
    public static void runRScript() throws RserveException, REXPMismatchException {
        // 创建RConnection实例，连接到本地运行的Rserve
        RConnection c = new RConnection();

        // 执行R代码，创建变量x和y，x为1到10的序列，y为x的平方
        c.eval("x <- 1:10");
        c.eval("y <- x^2");

        // 获取结果，将R中的x和y序列转换为Java的double数组
        double[] x = c.eval("x").asDoubles();
        double[] y = c.eval("y").asDoubles();

        // 打印结果，遍历数组x和y，输出每个元素的值
        for (int i = 0; i < x.length; i++) {
            System.out.println("x[" + i + "] = " + x[i] + ", y[" + i + "] = " + y[i]);
        }


        // 关闭连接，释放资源
        c.close();
    }
}
